package game;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Scanner;
import java.util.Vector;

import util.INIGroup;
import util.Util;

public class TileMap implements Loadable, ActionListener {
	private String tag;
	private int width = 0;
	private int height = 0;
	private String tileSetName;
	private TileSet tileSet = null;
	private Tile[][] map = null;
	private String[][] smap = null;
	private static Vector<Tile> tileList = new Vector<Tile>();
	private int pStartX = 0;
	private int pStartY = 0;
	
	private Vector<Character> chars = new Vector<Character>();
	private Vector<Item> groundItems = new Vector<Item>();
	private Vector<Portal> portals = new Vector<Portal>();
	
	public static void clearTiles()
	{
		tileList.clear();
	}
	
	public Vector<Character> getCharacters()
	{
		return chars;
	}
	
	public Vector<Item> getItems()
	{
		return groundItems;
	}
	
	public void addCharacter(Character c, int x, int y) //throws Exception
	{
		if(x < 0 || y < 0 || x >= width || y >= width)
		{
			System.out.println("Van mape! " + c.getName() + " (" + x + ", " + y + ")");
			return;
		}
		chars.add(c);
		//TODO c.setPosition(x, y);
		c.setPosX(x);
		c.setPosY(y);
		c.setMap(this);
	}
	
	public void addItem(Item i, int x, int y) throws Exception
	{
		if(x < 0 || y < 0 || x >= width || y >= width)
			throw new Exception("Van mape");
		groundItems.add(i);
		//TODO i.setPosition(x, y);
		i.setxPos(x);
		i.setyPos(y);
		i.setMap(this);
	}
	
	public void addPortal(Portal p)
	{
		portals.add(p);
	}
	
	public Portal getPortalAt(int x, int y)
	{
		for(Portal p : portals)
			if(p.getSrcX() == x && p.getSrcY() == y)
				return p;
		return null;
	}
	
	public void removeCharacter(Character c)
	{
		c.setMap(null);
		chars.remove(c);
	}
	
	public void removeItems(Item i)
	{
		groundItems.remove(i);
		i.setMap(null);
	}
	
	public Vector<Character> getCharactersAt(int x, int y)
	{
		Vector<Character> list = new Vector<Character>();
		for(Character c : chars)
		{
			if(c.getPosX() == x && c.getPosY() == y) list.add(c);
		}
		return list;
	}
	
	public Vector<Item> getItemsAt(int x, int y)
	{
		Vector<Item> list = new Vector<Item>();
		for(Item i : groundItems)
		{
			if(i.getxPos() == x && i.getyPos() == y) list.add(i);
		}
		return list;
	}
	
	public ItemContainer getContainerAt(int x, int y)
	{
		Vector<Item> list = new Vector<Item>();
		for(Item i : groundItems)
		{
			if(i.getxPos() == x && i.getyPos() == y) list.add(i);
		}
		if(list.size() == 0)
		{
			return null;
		}
		else
		{
			ItemContainer ic = new ItemContainer(list, 10, 1000);
			ic.addActionListener(this);
			return ic;
		}
	}
	
	public Character getCharacterAt(int x, int y)
	{
		for(Character c : chars)
			if(c.getPosX() == x && c.getPosY() == y) 
				return c;
		return null;
	}
	
	public Item getItemAt(int x, int y)
	{		
		for(Item i : groundItems)
			if(i.getxPos() == x && i.getyPos() == y) return i;
		return null;
	}

	@Override
	public boolean loadFromFile(INIGroup grupa) {
		width = Integer.parseInt(grupa.vals.get("Width"));
		height = Integer.parseInt(grupa.vals.get("Height"));
		String fname = grupa.vals.get("RawTiles");
		pStartX = Integer.parseInt(grupa.vals.get("PlayerX"));
		pStartY = Integer.parseInt(grupa.vals.get("PlayerY"));
		tileSetName = grupa.vals.get("TileSet");
		tag = grupa.vals.get("Tag");
		
		map = null; //new Tile[width][height];
		smap = new String[width][height];
		
		try {
			File f = new File(Util.fixPath(GameBase.DATA_FOLDER + fname));
			Scanner s = new Scanner(f);
			for(int y = 0; y < height; ++y)
			{
				String l = s.nextLine();
				for(int x = 0; x < width; ++x)
				{
					String t = l.substring(x, x + 1);
					smap[x][y] = t;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Fajld tu loud level : " + e.getMessage());
		}
		
		return true;
	}
	
	public Tile getTileAt(int x, int y)
	{
		if(x < 0 || x >= width || y < 0 || y >= height) return null;
		return map[x][y];
	}
	
	public int getWidth() { return width; }
	public int getHeight() { return height; }
	
	public String toString()
	{
		return "Tilemap " + width + " x " + height;
	}

	@Override
	public String getTag() {
		return tag;
	}

	@Override
	public void init() {
		tileSet = GameBase.getTileSetByTag(tileSetName);
		if(tileSet == null)
		{
			System.out.println("Error loading map - tile set \n" + tileSetName + "\" not found!");
			return;
		}
		map = new Tile[width][height];
		for(int y = 0; y < height; ++y)
			for(int x = 0; x < width; ++x)
			{
				Tile t = tileSet.getTile(smap[x][y]);
				if(t == null) { System.out.println("Hole in the map at " + x + ", " + y); }
				map[x][y] = t;
			}
	}
	
	public int getpStartX() {
		return pStartX;
	}

	public int getpStartY() {
		return pStartY;
	}
	
	public boolean inMap(int x, int y)
	{
		return x >= 0 && y >= 0 && x < width && y < height;
	}

	@Override
	public void actionPerformed(ActionEvent e)
	{
		if("item-remove".equals(e.getActionCommand()))
		{
			System.out.println("item-remove!!11");
			groundItems.remove(e.getSource());
		}
	}

}
